package cubelabs.nexus.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cubelabs.nexus.domain.CategoryDTO;
import cubelabs.nexus.domain.CategoryResponse;
import cubelabs.nexus.domain.CounselEventCreationRequest;
import cubelabs.nexus.domain.CounselRequestDTO;
import cubelabs.nexus.domain.CounselRequestResponse;
import cubelabs.nexus.domain.CounsellingEventReview;
import cubelabs.nexus.domain.SessionData;
import cubelabs.nexus.domain.UserDTO;
import cubelabs.nexus.domain.UserResponse;
import cubelabs.nexus.entity.Category;
import cubelabs.nexus.entity.CounsellingEvent;
import cubelabs.nexus.entity.CounsellingEventStatus;
import cubelabs.nexus.entity.CounsellingSession;
import cubelabs.nexus.entity.User;
import cubelabs.nexus.entity.UserCategory;
import cubelabs.nexus.service.NexusService;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {

	private static final Logger logger = LoggerFactory
			.getLogger(HomeController.class);

	@Autowired
	private NexusService nexuService;
	
	@RequestMapping(consumes="application/json",value="/login",method=RequestMethod.POST)
	public @ResponseBody UserDTO login(@RequestBody UserDTO userDTO, HttpServletRequest request,HttpServletResponse response) throws Exception {
			
		if(userDTO != null){
			User user = nexuService.fetchUserByEmail(userDTO.getEmail());
			if(user == null){
				user = nexuService.createUser(userDTO);
			}/*else{
				nexuService.updateLoginTime(user);
			}*/
			userDTO.setEmail(user.getEmail());
			userDTO.setName(user.getName());
			userDTO.setImagePath(user.getImagePath());
			userDTO.setId(user.getId());
			request.getSession().setAttribute("user", user);
		}

		
		return userDTO;
	}

	/**
	 * Simply selects the user by userId.
	 */
	@RequestMapping(value = "/user/{userId}")
	public @ResponseBody
	UserDTO getUserById(@PathVariable("userId") Long userId,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		User user;
		if(userId == -1){
		user =	(User) request.getSession().getAttribute("user");
		}else{
			user = nexuService.fetchUserById(userId);
		}
		
		UserDTO userDTO = new UserDTO();
		userDTO.setEmail(user.getEmail());
		userDTO.setName(user.getName());
		userDTO.setImagePath(user.getImagePath());
		userDTO.setId(user.getId());
		return userDTO;
	}

	/**
	 * Simply selects the user by categoryId.
	 */
	@RequestMapping(value = "/category/{categoryId}/user")
	public @ResponseBody
	UserResponse getUsersByCategory(
			@PathVariable("categoryId") Long categoryId,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		UserResponse userResponse = new UserResponse();
		User user = (User) request.getSession().getAttribute("user");
		userResponse
				.setUserDTOs(nexuService.fetchUsersByCategoryId(categoryId,user));
		
		if(user != null){
			userResponse.setAddToCategory(nexuService.isUserInCategory(categoryId, user.getId()));
		}else{
			userResponse.setAddToCategory(true);
		}
		
		userResponse.setId(categoryId);
		
		return userResponse;
	}

	/**
	 * Simply selects the list of categories.
	 */
	@RequestMapping(value = "/category")
	public @ResponseBody
	CategoryResponse getCategories(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		CategoryResponse categoryResponse = new CategoryResponse();
		List<Category> categories = nexuService.findAllCategories();
		List<CategoryDTO> categoryDTOList = new ArrayList<CategoryDTO>();
		if(categories != null){
			for(Category category : categories){
				CategoryDTO categoryDTO = new CategoryDTO();
				categoryDTO.setId(category.getId());
				categoryDTO.setIconPath(category.getIconPath());
				categoryDTO.setName(category.getName());
				categoryDTOList.add(categoryDTO);
			}
		}
		
		categoryResponse.setCategoryDTOList(categoryDTOList);
		return categoryResponse;
	}

	/**
	 * Simply selects the list of categories.
	 */
	@RequestMapping(value = "/user/{userId}/review")
	public @ResponseBody
	List<CounsellingEventReview> getUserReview(
			@PathVariable("userId") Long userId, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		return nexuService.findReviewByUserId(userId);
	}

	/**
	 * Simply selects the list of counsel requests for user.
	 */
	@RequestMapping(value = "/counsel/user")
	public @ResponseBody
	CounselRequestResponse getCounselRequestsForUser(
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		System.out.println(request.getSession().getAttribute("user"));
		User user = (User) request.getSession().getAttribute("user");

		CounselRequestResponse counselRequestResponse = new CounselRequestResponse();
		List<CounselRequestDTO> counselRequestDTOList = nexuService
				.findCounselRequestsByUserId(user.getId());

		counselRequestResponse.setCounselRequestDTO(counselRequestDTOList);
		return counselRequestResponse;
	}
	


	@RequestMapping(value = "counsel/{userId}/addCounselRequest")
	public @ResponseBody
	CounselRequestResponse addCounselRequest(@RequestBody CounselEventCreationRequest counselEventCreationRequest,@PathVariable("userId") Long toUserId,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {

		System.out.println(request.getSession().getAttribute("user"));
		User frmUser = (User) request.getSession().getAttribute("user");

		
		User toUser = nexuService.fetchUserById(toUserId);
		
		CounsellingEvent counsellingEvent = new CounsellingEvent();
		counsellingEvent.setActive(true);
		/*CounsellingAcceptor counsellingAcceptor = new CounsellingAcceptor();
		counsellingAcceptor.setUser(frmUser);
		*/
		//counsellingEvent.setCounsellingAcceptor(counsellingAcceptor);
		counsellingEvent.setDiscription(counselEventCreationRequest.getDescription());
		counsellingEvent.setFrmUser(frmUser);
		//counsellingEvent.setCounsellingAcceptor(counsellingAcceptor);
		counsellingEvent.setToUser(toUser);
		Date startDate;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
		
		startDate = sdf.parse(counselEventCreationRequest.getStartTime());
		counsellingEvent.setStart(startDate);
		
		Date endDate;
		endDate = sdf.parse(counselEventCreationRequest.getEndTime());
		counsellingEvent.setEnd(endDate);
		counsellingEvent.setCounsellingEventStatus(CounsellingEventStatus.Active);
		nexuService.createEvent(counsellingEvent);
		
		CounselRequestResponse counselRequestResponse = new CounselRequestResponse();
		List<CounselRequestDTO> counselRequestDTOList = nexuService
				.findCounselRequestsByUserId(frmUser.getId());

		counselRequestResponse.setCounselRequestDTO(counselRequestDTOList);
		
		return counselRequestResponse;
	}
	
	@RequestMapping(value="/user",method=RequestMethod.POST)
	public @ResponseBody UserDTO postUser(@RequestBody UserDTO userDTO,HttpServletRequest request,HttpServletResponse response) throws Exception {
		
		nexuService.createUser(userDTO);
		
		return userDTO;
	}
	
	@RequestMapping(value="/category",method=RequestMethod.POST)
	public @ResponseBody CategoryDTO createCategory(@RequestBody CategoryDTO categoryDTO){
		
		nexuService.createCategory(categoryDTO);
		
		return categoryDTO;
	}
	
	@RequestMapping(value="/category/{categoryId}/addUser")
	public @ResponseBody String addUserToCategory(@PathVariable("categoryId") Long categoryId, HttpServletRequest request){
		
		User frmUser = (User) request.getSession().getAttribute("user");
		UserCategory category = nexuService.addUserToCategory(categoryId, frmUser.getId());
		//userResponse.setUserDTOs(GenericUtils.getUserDTO(category.getUsers()));
		return "success";
	}
	

	@RequestMapping(value="counsel/{counselEventId}/session")
	public @ResponseBody SessionData initSession(@PathVariable("counselEventId") Long counselEventId){
		
		SessionData sessionData2 = nexuService.fetchSession(counselEventId);
		if(sessionData2 == null){
			CounsellingSession counsellingSession = nexuService.saveCounsellingSession(counselEventId);
			sessionData2 = new SessionData();
			sessionData2.setApiKey(21313161);
			sessionData2.setModeratorToken(counsellingSession.getModeratorToken());
			sessionData2.setPublisherToken(counsellingSession.getPublisherToken());
			sessionData2.setSessionId(counsellingSession.getSessionId());
			sessionData2.setSubscriberToken(counsellingSession.getSubscriberToken());
			sessionData2.setToken(counsellingSession.getToken());
		}
		return sessionData2;
	}

	@RequestMapping(value="counsel/{counselEventId}/stopSession")
	public @ResponseBody SessionData stopSession(@PathVariable("counselEventId") Long counselEventId){
		
		SessionData sessionData2 = nexuService.stopSession(counselEventId);
		return sessionData2;
	}
	
	@RequestMapping(value = "/logout")
	public @ResponseBody
	String logoutUser(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		request.getSession().removeAttribute("user");
		return "success";
	}

}
